package com.jl15988.mybatispluskit.join.injector.methods;

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.jl15988.mybatispluskit.join.enums.JoinSqlMethod;

/**
 * 关联查询方法抽象基类
 * 提供通用的 SQL 构建方法
 * 
 * @author Jalon
 * @since 2025/1/1
 */
public abstract class AbstractJoinMethod extends AbstractMethod {
    
    /**
     * SQL 方法枚举
     */
    protected final JoinSqlMethod sqlMethod;
    
    /**
     * 构造函数
     * 
     * @param sqlMethod SQL 方法枚举
     */
    protected AbstractJoinMethod(JoinSqlMethod sqlMethod) {
        super(sqlMethod.getMethod());
        this.sqlMethod = sqlMethod;
    }
    
    /**
     * 构建查询字段 SQL 片段
     * 
     * @param hasSelectSql 是否有自定义查询字段
     * @param mainTableAlias 主表别名
     * @return 查询字段 SQL 片段
     */
    protected String buildSelectSql(boolean hasSelectSql, String mainTableAlias) {
        if (hasSelectSql) {
            return "${ew.selectSql}";
        } else {
            return mainTableAlias + ".*";
        }
    }
    
    /**
     * 构建 JOIN 子句 SQL 片段
     * 
     * @return JOIN 子句 SQL 片段
     */
    protected String buildJoinSql() {
        return "<foreach collection=\"ew.joinInfos\" item=\"join\">\n" +
               "  ${join.joinType.sql} ${join.joinTableName} ${join.joinTableAlias}\n" +
               "  ON ${join.mainTableAlias}.${join.mainField} = ${join.joinTableAlias}.${join.joinField}\n" +
               "</foreach>";
    }
    
    /**
     * 构建 WHERE 子句 SQL 片段
     * 
     * @return WHERE 子句 SQL 片段
     */
    protected String buildWhereSql() {
        return "<if test=\"ew.sqlSegment != null and ew.sqlSegment != ''\">\n" +
               "  WHERE ${ew.sqlSegment}\n" +
               "</if>";
    }
    
    /**
     * 构建完整的 SQL 语句
     * 
     * @param tableInfo 表信息
     * @param selectColumns 查询字段（null 表示使用主表所有字段）
     * @return 完整的 SQL 语句
     */
    protected String buildSql(TableInfo tableInfo, String selectColumns) {
        String mainTableName = tableInfo.getTableName();
        String mainTableAlias = "${ew.mainTableAlias}";
        String selectSql = selectColumns != null ? selectColumns : buildSelectSql(true, mainTableAlias);
        String joinSql = buildJoinSql();
        String whereSql = buildWhereSql();
        
        return String.format(sqlMethod.getSql(), selectSql, mainTableName, mainTableAlias, joinSql, whereSql);
    }
} 